package com.wqnmdb.im.netty.handler.impl;

import com.wqnmdb.im.domain.mongo.ImUser;
import com.wqnmdb.im.domain.netty.contants.NettyIdentifier;
import com.wqnmdb.im.domain.netty.protobuf.Authentication;
import com.wqnmdb.im.domain.netty.protobuf.NettyModel;
import com.wqnmdb.im.netty.dispose.MsgDispose;
import com.wqnmdb.im.netty.dispose.NettyDispose;
import com.wqnmdb.im.netty.dispose.impl.DataAndCheckService;
import com.wqnmdb.im.netty.handler.BaseHandler;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;


/**
 * 认证Handler
 */
@Slf4j
@ChannelHandler.Sharable
public class AuthHandler extends ChannelInboundHandlerAdapter implements BaseHandler {

    private final NettyDispose nettyDispose = getNettyDispose();

    private final DataAndCheckService dataAndCheckService = getDataAndCheckService();

    private final MsgDispose msgDispose = getMsgDispose();


    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        NettyModel.ReqModel reqModel = (NettyModel.ReqModel) msg;
        Authentication.Auth auth = reqModel.getAuth();
        Channel channel = ctx.channel();

        //检查是否认证过
        if (channel.hasAttr(NettyIdentifier.AUTH_KEY) && channel.attr(NettyIdentifier.AUTH_KEY).get()) {
            //执行消息相关指令 传递下一个控制器
            ctx.fireChannelRead(msg);
        } else if (auth != null && StringUtils.isNotBlank(auth.getAccessKey())
                && StringUtils.isNotBlank(auth.getSecretKey())
                && StringUtils.isNotBlank(auth.getAppName())) {
            log.info("权鉴控制器加载客户端报文:{}.", msg);
            //检查身份信息并获取用户对象
            ImUser user = dataAndCheckService.checkUserAuth(auth.getAccessKey(), auth.getSecretKey(), auth.getAppName());
            if (user == null) {
                ctx.close();
            } else {
                //检查这个用户是否已经绑定了
                if (dataAndCheckService.checkUserBinding(auth.getAppName(), user.getUserId())) {
                    ctx.close();
                } else {
                    //绑定管道
                    nettyDispose.bindingUserChannel(user, auth.getAppName(), ctx);
                    msgDispose.auth(ctx, user);
                }
            }
        } else {
            nettyDispose.remove(ctx);
        }
    }
}
